﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Input;

namespace lumo.input
{
    /// <summary>
    /// 
    /// </summary>
    public class TextListener : IUpdatableOnce
    {
        /// <summary>
        /// Text listened.
        /// </summary>
        public string Text = "";

        // Internal variables
        private List<Keypad>  KeypadList = new List<Keypad>();
        private InputWrapper  ShiftWrapper = new InputWrapper();
        private InputListener Listener = new InputListener();

        // The propertie for frame ID
        private uint _FrameID = 0;
        /// <summary>Access for FrameID</summary>
        public uint FrameID { get { return _FrameID; } }

        // Keys used
        static private Keys[] UsedKeys = new Keys[] { 
            Keys.A, Keys.B, Keys.C, Keys.D, Keys.E, 
            Keys.F, Keys.G, Keys.H, Keys.I, Keys.J,
            Keys.K, Keys.L, Keys.M, Keys.N, Keys.O,
            Keys.P, Keys.Q, Keys.R, Keys.S, Keys.T,
            Keys.U, Keys.V, Keys.W, Keys.X, Keys.Y,
            Keys.Z, 

            Keys.D0, Keys.D1, Keys.D2, Keys.D3, Keys.D4, 
            Keys.D5, Keys.D6, Keys.D7, Keys.D8, Keys.D9,

            Keys.NumPad0, Keys.NumPad1, Keys.NumPad2, Keys.NumPad3, Keys.NumPad4, 
            Keys.NumPad5, Keys.NumPad6, Keys.NumPad7, Keys.NumPad8, Keys.NumPad9,
            
            Keys.Space,

            Keys.Back,
        };

        /// <summary>
        /// Add a keypad to listen to the text.
        /// </summary>
        /// <param name="Keypad">The keypad</param>
        /// <param name="UpdateKeypad">Update the Keypad?</param>
        public void Add(Keypad Keypad, bool UpdateKeypad = true)
        {
            // 
            if (UpdateKeypad)
                KeypadList.Add(Keypad);

            // Add the used keys
            foreach (Keys key in UsedKeys)
                Listener.Add(Keypad.GetKey(key), false);

            // Shifts
            ShiftWrapper.Add(Keypad.GetKey(Keys.RightShift), false);
            ShiftWrapper.Add(Keypad.GetKey(Keys.LeftShift), false);
        }

        /// <summary>
        /// Clear the Keypads
        /// </summary>
        public void Clear()
        {
            KeypadList.Clear();
            Listener.Clear();
        }

        /// <summary>
        /// Update the listener.
        /// </summary>
        /// <param name="Game">The game class.</param>
        public void Update(LumoComponent Game)
        {
            // Only called once per frame.
            if (_FrameID == Game.FrameID)
                return;
            _FrameID = Game.FrameID;

            foreach (Keypad keypad in KeypadList)
                keypad.Update(Game);

            Listener.Update(Game);
            ShiftWrapper.Update(Game);

            bool Shift = ShiftWrapper.Pressed;

            foreach (IInputObject obj in Listener.GetKeys())
            {
                Keys key = (Keys)obj.GetInputID();
                switch (key)
                {
                    case Keys.A: { Text += (Shift ? "A" : "a"); break; }
                    case Keys.B: { Text += (Shift ? "B" : "b"); break; }
                    case Keys.C: { Text += (Shift ? "C" : "c"); break; }
                    case Keys.D: { Text += (Shift ? "D" : "d"); break; }
                    case Keys.E: { Text += (Shift ? "E" : "e"); break; }
                    case Keys.F: { Text += (Shift ? "F" : "f"); break; }
                    case Keys.G: { Text += (Shift ? "G" : "g"); break; }
                    case Keys.H: { Text += (Shift ? "H" : "h"); break; }
                    case Keys.I: { Text += (Shift ? "I" : "i"); break; }
                    case Keys.J: { Text += (Shift ? "J" : "j"); break; }
                    case Keys.K: { Text += (Shift ? "K" : "k"); break; }
                    case Keys.L: { Text += (Shift ? "L" : "l"); break; }
                    case Keys.M: { Text += (Shift ? "M" : "m"); break; }
                    case Keys.N: { Text += (Shift ? "N" : "n"); break; }
                    case Keys.O: { Text += (Shift ? "O" : "o"); break; }
                    case Keys.P: { Text += (Shift ? "P" : "p"); break; }
                    case Keys.Q: { Text += (Shift ? "Q" : "q"); break; }
                    case Keys.R: { Text += (Shift ? "R" : "r"); break; }
                    case Keys.S: { Text += (Shift ? "S" : "s"); break; }
                    case Keys.T: { Text += (Shift ? "T" : "t"); break; }
                    case Keys.U: { Text += (Shift ? "U" : "u"); break; }
                    case Keys.V: { Text += (Shift ? "V" : "v"); break; }
                    case Keys.W: { Text += (Shift ? "W" : "w"); break; }
                    case Keys.X: { Text += (Shift ? "X" : "x"); break; }
                    case Keys.Y: { Text += (Shift ? "Y" : "y"); break; }
                    case Keys.Z: { Text += (Shift ? "Z" : "z"); break; }
                    case Keys.D0:
                    case Keys.NumPad0: { Text += "0"; break; }
                    case Keys.D1:
                    case Keys.NumPad1: { Text += "1"; break; }
                    case Keys.D2:
                    case Keys.NumPad2: { Text += "2"; break; }
                    case Keys.D3:
                    case Keys.NumPad3: { Text += "3"; break; }
                    case Keys.D4:
                    case Keys.NumPad4: { Text += "4"; break; }
                    case Keys.D5:
                    case Keys.NumPad5: { Text += "5"; break; }
                    case Keys.D6:
                    case Keys.NumPad6: { Text += "6"; break; }
                    case Keys.D7:
                    case Keys.NumPad7: { Text += "7"; break; }
                    case Keys.D8:
                    case Keys.NumPad8: { Text += "8"; break; }
                    case Keys.D9:
                    case Keys.NumPad9: { Text += "9"; break; }

                    // Space check
                    case Keys.Space: { Text += " "; break; }

                    // Backspace Check
                    case Keys.Back:  { if (Text.Length > 0) Text = Text.Substring(0, Text.Length - 1); break; }
                }
            }
        }
    }
}
